# GCC路径
GCC_PATH = /usr/bin
PWD=`pwd`

# 目标名字
TARGET = STM32F429

BUILD_DIR = build

################# STM32F4xx_HAL ###########################

STM32F4XX_HAL ?= ../../STM32F4xx_HAL

C_INCLUDES = \
    -I. \
    -I$(STM32F4XX_HAL)/inc \
    -I$(STM32F4XX_HAL)/CMSIS/Device/ST/STM32F4xx/Include \
    -I$(STM32F4XX_HAL)/CMSIS/Include

C_SOURCES = \
    $(STM32F4XX_HAL)/CMSIS/Device/ST/STM32F4xx/Source/system_stm32f4xx.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_adc.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_dac.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_dac_ex.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_adc_ex.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_can.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_cortex.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_crc.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_cryp.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_dcmi.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_dma.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_dma_ex.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_dma2d.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_eth.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_exti.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_flash.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_flash_ex.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_nand.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_ll_fmc.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_nor.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_pccard.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_pwr_ex.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_sram.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_hash.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_gpio.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_i2c.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_i2s.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_i2s_ex.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_ltdc.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_rcc.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_rcc_ex.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_rng.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_rtc.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_rtc_ex.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_sai.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_sai_ex.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_sd.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_ll_sdmmc.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_sdram.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_spi.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_tim.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_tim_ex.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_uart.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_usart.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_irda.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_smartcard.c \
    $(STM32F4XX_HAL)/src/stm32f4xx_hal_wwdg.c

################### miniFreeRTOS #############################

FreeRTOS ?= ../../../../kernel
C_INCLUDES += \
    -I$(FreeRTOS)/include \
    -I$(FreeRTOS)

C_SOURCES +=  \
    $(FreeRTOS)/list.c \
    $(FreeRTOS)/irq.c \
    $(FreeRTOS)/tasks.c \
    $(FreeRTOS)/mm.c \
    $(FreeRTOS)/queue.c \
    $(FreeRTOS)/mutex.c


####################### lwip #############################

LWIPDIR_SRC ?= ../../../../external/lwip/src
LWIPDIR ?= ../../../../external/lwip
LWIPDIR_ARCH ?= ../../../../external/lwip/arch

C_INCLUDES += \
    -I$(LWIPDIR_SRC)/include \
    -I$(LWIPDIR_ARCH) \
    -I$(LWIPDIR)

#lwip arch
C_SOURCES += \
    $(LWIPDIR_ARCH)/ethernetif.c \
    $(LWIPDIR_ARCH)/lwip_comm.c \
    $(LWIPDIR_ARCH)/sys_arch.c
#lwip
C_SOURCES += \
	$(LWIPDIR_SRC)/core/init.c \
	$(LWIPDIR_SRC)/core/def.c \
	$(LWIPDIR_SRC)/core/dns.c \
	$(LWIPDIR_SRC)/core/inet_chksum.c \
	$(LWIPDIR_SRC)/core/ip.c \
	$(LWIPDIR_SRC)/core/mem.c \
	$(LWIPDIR_SRC)/core/memp.c \
	$(LWIPDIR_SRC)/core/netif.c \
	$(LWIPDIR_SRC)/core/pbuf.c \
	$(LWIPDIR_SRC)/core/raw.c \
	$(LWIPDIR_SRC)/core/stats.c \
	$(LWIPDIR_SRC)/core/sys.c \
	$(LWIPDIR_SRC)/core/tcp.c \
	$(LWIPDIR_SRC)/core/tcp_in.c \
	$(LWIPDIR_SRC)/core/tcp_out.c \
	$(LWIPDIR_SRC)/core/timeouts.c \
	$(LWIPDIR_SRC)/core/udp.c

# ipv4
C_SOURCES += \
	$(LWIPDIR_SRC)/core/ipv4/autoip.c \
	$(LWIPDIR_SRC)/core/ipv4/dhcp.c \
	$(LWIPDIR_SRC)/core/ipv4/etharp.c \
	$(LWIPDIR_SRC)/core/ipv4/icmp.c \
	$(LWIPDIR_SRC)/core/ipv4/igmp.c \
	$(LWIPDIR_SRC)/core/ipv4/ip4_frag.c \
	$(LWIPDIR_SRC)/core/ipv4/ip4.c \
	$(LWIPDIR_SRC)/core/ipv4/ip4_addr.c

#ipv6
C_SOURCES += \
	$(LWIPDIR_SRC)/core/ipv6/dhcp6.c \
	$(LWIPDIR_SRC)/core/ipv6/ethip6.c \
	$(LWIPDIR_SRC)/core/ipv6/icmp6.c \
	$(LWIPDIR_SRC)/core/ipv6/inet6.c \
	$(LWIPDIR_SRC)/core/ipv6/ip6.c \
	$(LWIPDIR_SRC)/core/ipv6/ip6_addr.c \
	$(LWIPDIR_SRC)/core/ipv6/ip6_frag.c \
	$(LWIPDIR_SRC)/core/ipv6/mld6.c \
	$(LWIPDIR_SRC)/core/ipv6/nd6.c

# APIFILES: The files which implement the sequential and socket APIs.
C_SOURCES += \
	$(LWIPDIR_SRC)/api/api_lib.c \
	$(LWIPDIR_SRC)/api/api_msg.c \
	$(LWIPDIR_SRC)/api/err.c \
	$(LWIPDIR_SRC)/api/netbuf.c \
	$(LWIPDIR_SRC)/api/netdb.c \
	$(LWIPDIR_SRC)/api/netifapi.c \
	$(LWIPDIR_SRC)/api/sockets.c \
	$(LWIPDIR_SRC)/api/tcpip.c

# NETIFFILES: Files implementing various generic network interface functions
C_SOURCES += \
	$(LWIPDIR_SRC)/netif/ethernet.c \
	$(LWIPDIR_SRC)/netif/slipif.c

# SIXLOWPAN: 6LoWPAN
C_SOURCES += \
	$(LWIPDIR_SRC)/netif/lowpan6.c

####################### modbus #############################
MODBUSDIR ?= ../../../../external/modbus
C_INCLUDES += \
	-I$(MODBUSDIR)

C_SOURCES += \
	$(MODBUSDIR)/modbus-data.c \
	$(MODBUSDIR)/modbus-tcp.c \
	$(MODBUSDIR)/modbus.c

# # ping
 C_SOURCES += \
 	$(LWIPDIR_SRC)/apps/ping/ping.c

# # tcp client
# C_SOURCES += \
# 	$(LWIPDIR_SRC)/apps/tcp/client/tcp_client.c

# # tcp server
# C_SOURCES += \
# 	$(LWIPDIR_SRC)/apps/tcp/server/tcp_server.c

# ftpd
C_SOURCES += \
	$(LWIPDIR_SRC)/apps/ftp/ftpd.c \
    $(LWIPDIR_SRC)/apps/ftp/vfs.c

C_INCLUDES += \
	-Idriver \
	-Idemo \
	-I.

####################### fatfs ###########################
FATFSDIR ?= ../../../../external/fatfs

C_INCLUDES += -I$(FATFSDIR)

# fatfs source
C_SOURCES += \
    $(FATFSDIR)/diskio.c \
    $(FATFSDIR)/ff.c \
    $(FATFSDIR)/ffsystem.c \
    $(FATFSDIR)/ffunicode.c

####################### lvgl #############################
# LVGLDIR ?= ../../../../external/lvgl
# LVGLDIR_CORE ?= ../../../../external/lvgl/src/core
# LVGLDIR_DRAW ?= ../../../../external/lvgl/src/draw
# LVGLDIR_FONT ?= ../../../../external/lvgl/src/font
# LVGLDIR_HAL ?= ../../../../external/lvgl/src/hal
# LVGLDIR_MISC ?= ../../../../external/lvgl/src/misc
# LVGLDIR_WIDGETS ?= ../../../../external/lvgl/src/widgets
# include ${LVGLDIR_CORE}/lv_core.mk
# include ${LVGLDIR_DRAW}/lv_draw.mk
# include ${LVGLDIR_FONT}/lv_font.mk
# include ${LVGLDIR_HAL}/lv_hal.mk
# include ${LVGLDIR_WIDGETS}/lv_widgets.mk
# C_SOURCES += ${CSRCS}

# LVGLDIR_DRAW ?= ../../../../external/lvgl/src/draw
# LVGLDIR_FONT ?= ../../../../external/lvgl/src/font
# LVGLDIR_HAL ?= ../../../../external/lvgl/src/hal
# LVGLDIR_MISC ?= ../../../../external/lvgl/src/misc
# LVGLDIR_WIDGETS ?= ../../../../external/lvgl/src/widgets

# C_INCLUDES += -I$(LVGLDIR)
# C_INCLUDES += -I$(LVGLDIR)/src
# C_INCLUDES += -I$(LVGLDIR)/examples/porting
# C_INCLUDES += -I$(LVGLDIR)/examples/get_started

# C_SOURCES +=  \
#     $(LVGLDIR)/examples/porting/lv_port_disp.c \
#     $(LVGLDIR)/examples/porting/lv_port_indev.c

# C_SOURCES += $(wildcard ${LVGLDIR_CORE}/*.c)
# C_SOURCES += $(wildcard ${LVGLDIR_DRAW}/*.c)
# C_SOURCES += $(wildcard ${LVGLDIR_FONT}/*.c)
# C_SOURCES += $(wildcard ${LVGLDIR_HAL}/*.c)
# C_SOURCES += $(wildcard ${LVGLDIR_MISC}/*.c)
# C_SOURCES += $(wildcard ${LVGLDIR_WIDGETS}/*.c)

# LVGLDIR_EXTRA_LAYOUT:=../../../../external/lvgl/src/extra/layouts/flex
# LVGLDIR_EXTRA_LAYOUT+=../../../../external/lvgl/src/extra/layouts/grid
# C_SOURCES += $(foreach dir, $(LVGLDIR_EXTRA_LAYOUT), $(wildcard $(dir)/*.c))

# LVGLDIR_EXTRA_THEMES:=../../../../external/lvgl/src/extra/layouts/basic
# LVGLDIR_EXTRA_THEMES+=../../../../external/lvgl/src/extra/layouts/default
# LVGLDIR_EXTRA_THEMES+=../../../../external/lvgl/src/extra/layouts/mono

# C_SOURCES += $(foreach dir, $(LVGLDIR_EXTRA_THEMES), $(wildcard $(dir)/*.c))

# LVGLDIR_EXTRA+=../../../../external/lvgl/src/themes
# LVGLDIR_EXTRA:=../../../../external/lvgl/src/widgets

# C_SOURCES += $(foreach dir, $(dirs), $(wildcard $(dir)/*.c))
# C_SOURCES += $(LVGLDIR)/src/extra/lv_extra.c

###################### Application #######################
C_SOURCES += \
    driver/system.c \
    driver/usart.c \
    driver/ethernet_driver.c \
    driver/ethernet_chip.c \
    driver/sdio_sdcard.c \
    # driver/ltdc.c

C_SOURCES += printf.c
C_SOURCES += demo/ftpd_demo.c
# C_SOURCES += demo/semaphore_binary.c
# C_SOURCES += demo/semaphore_counting.c
# C_SOURCES += semaphore_mutex.c
# C_SOURCES += demo/timer_demo.c
# C_SOURCES += demo/queue_demo.c
#C_SOURCES += demo/event_group_demo.c
#C_SOURCES += demo/task_notify_demo.c
# C_SOURCES += demo/tickless_demo.c
C_SOURCES += demo/tcp_modbus_server.c
# C_SOURCES += demo/tcp_modbus_client.c
# C_SOURCES += demo/fatfs_demo.c
# C_SOURCES += demo/modbus_demo.c
C_SOURCES += demo/task_demo.c
#C_SOURCES += demo/lvgl_demo.c

C_SOURCES += \
    main.c

############################ Boot #######################

# ASM sources
ASM_SOURCES =  startup.s

######################### build flags ###################
# debug build?
DEBUG = 1
# optimization
OPT = -Og
PREFIX = arm-none-eabi-
CC = $(GCC_PATH)/$(PREFIX)gcc
AS = $(GCC_PATH)/$(PREFIX)gcc -x assembler-with-cpp
CP = $(GCC_PATH)/$(PREFIX)objcopy
SZ = $(GCC_PATH)/$(PREFIX)size
HEX = $(CP) -O ihex
BIN = $(CP) -O binary -S
AS_DEFS =

# C defines
C_DEFS =  \
-DUSE_STDPERIPH_DRIVER \
-DSTM32F429xx

# compile gcc flags
ASFLAGS = -mcpu=cortex-m4 $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
CFLAGS = -mcpu=cortex-m4 $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
CFLAGS += -mlittle-endian -mthumb
CFLAGS += -mfpu=fpv4-sp-d16 -mfloat-abi=softfp

ifeq ($(DEBUG), 1)
CFLAGS += -g -gdwarf-2
endif

# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
# link script
LDSCRIPT = arm-gcc.ld

# libraries
LIBS = -lc -lm -lnosys
LIBDIR =
LDFLAGS = -mcpu=cortex-m4 -specs=nano.specs -T$(LDSCRIPT) $(LIBDIR) $(LIBS) -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref -Wl,--gc-sections

# default action: build all
all: $(BUILD_DIR)/$(TARGET).elf $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).bin


# list of objects
OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))
# list of ASM program objects
OBJECTS += $(addprefix $(BUILD_DIR)/,$(notdir $(ASM_SOURCES:.s=.o)))
vpath %.s $(sort $(dir $(ASM_SOURCES)))

$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR)
	$(CC) -c $(CFLAGS) -Wa,-a,-ad,-alms=$(BUILD_DIR)/$(notdir $(<:.c=.lst)) $< -o $@

$(BUILD_DIR)/%.o: %.s Makefile | $(BUILD_DIR)
	$(AS) -c $(CFLAGS) $< -o $@

$(BUILD_DIR)/$(TARGET).elf: $(OBJECTS) Makefile
	$(CC) $(OBJECTS) $(LDFLAGS) -o $@
	$(SZ) $@

$(BUILD_DIR)/%.hex: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(HEX) $< $@

$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(BIN) $< $@

$(BUILD_DIR):
	mkdir $@


clean:
	-rm -fR $(BUILD_DIR)

-include $(wildcard $(BUILD_DIR)/*.d)
